package com.wiyun.engine.skeleton;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.content.res.AssetManager;

import com.wiyun.engine.actions.Action;
import com.wiyun.engine.actions.Action.Callback;
import com.wiyun.engine.actions.Animate;
import com.wiyun.engine.actions.IntervalAction;
import com.wiyun.engine.actions.MoveBy;
import com.wiyun.engine.actions.MoveTo;
import com.wiyun.engine.actions.RepeatForever;
import com.wiyun.engine.actions.Sequence;
import com.wiyun.engine.nodes.Animation;
import com.wiyun.engine.nodes.Animation.IAnimationCallback;
import com.wiyun.engine.nodes.Sprite;
import com.wiyun.engine.opengl.Texture2D;

public class AnimationRole  {

	private Animation player_left_anim, player_right_anim, player_up_anim, player_down_anim, 
	player_upright_anim, player_rightdown_anim, player_leftup_anim, player_downleft_anim, 
	player_leftface_anim, player_rightface_anim, player_upface_anim, player_downface_anim, //face
	player_uprightface_anim, player_rightdownface_anim, player_leftupface_anim, player_downleftface_anim, 
	player_leftattack_anim, player_rightattack_anim, player_upattack_anim, player_downattack_anim, //attack
	player_uprightattack_anim, player_rightdownattack_anim, player_leftupattack_anim, player_downleftattack_anim;
	String _role;
	float _durp;
	IAnimationCallback _callback;
	AssetManager _assetMgr;
	float _speed;
	//String[] FlipDirection = new String[]{""};
	
	public Animation GetLeft()
	{
		return player_left_anim;
	}
	public Animation GetRight()
	{
		return player_right_anim;
	}
	public Animation GetUp()
	{
		return player_up_anim;
	}
	public Animation GetDown()
	{
		return player_down_anim;
	}
	public Animation GetUpright()
	{
		return player_upright_anim;
	}
	public Animation GetRightdown()
	{
		return player_rightdown_anim;
	}
	public Animation GetLeftup()
	{
		return player_leftup_anim;
	}
	public Animation GetDownleft()
	{
		return player_downleft_anim;
	}
	
	public int GetDirectionByTan(double targetX, double targetY, double currentX, double currentY) {
        double tan = (targetY - currentY) / (targetX - currentX);
        if (Math.abs(tan) >= Math.tan(Math.PI * 3 / 8) && targetY <= currentY) {
            return 4;
        } else if (Math.abs(tan) > Math.tan(Math.PI / 8) && Math.abs(tan) < Math.tan(Math.PI * 3 / 8) && targetX > currentX && targetY < currentY) {
            return 3;
        } else if (Math.abs(tan) <= Math.tan(Math.PI / 8) && targetX >= currentX) {
            return 2;
        } else if (Math.abs(tan) > Math.tan(Math.PI / 8) && Math.abs(tan) < Math.tan(Math.PI * 3 / 8) && targetX > currentX && targetY > currentY) {
            return 1;
        } else if (Math.abs(tan) >= Math.tan(Math.PI * 3 / 8) && targetY >= currentY) {
            return 0;
        } else if (Math.abs(tan) > Math.tan(Math.PI / 8) && Math.abs(tan) < Math.tan(Math.PI * 3 / 8) && targetX < currentX && targetY > currentY) {
            return 7;
        } else if (Math.abs(tan) <= Math.tan(Math.PI / 8) && targetX <= currentX) {
            return 6;
        } else if (Math.abs(tan) > Math.tan(Math.PI / 8) && Math.abs(tan) < Math.tan(Math.PI * 3 / 8) && targetX < currentX && targetY < currentY) {
            return 5;
        } else {
            return 0;
        }
    }
	public void SetRunAction(Sprite sprite, float startX, float startY, float targetX, float targetY)
	{
		int direction = GetDirectionByTan(targetX, targetY, startX, startY);
		boolean isFilpX=false;
		Animation anim = player_leftup_anim;
		if(direction==0)
			anim=player_up_anim;
		if(direction==1)
			anim=player_upright_anim;
		if(direction==2)
			anim=player_right_anim;
		if(direction==3)
			anim=player_rightdown_anim;
		if(direction==4)
			anim=player_down_anim;
		if(direction==5)
			{anim=player_downleft_anim;isFilpX=true;}
		if(direction==6)
			{anim=player_left_anim;isFilpX=true;}
		if(direction==7)
			{anim=player_leftup_anim;isFilpX=true;}
		float duration = (float) Math.sqrt(Math.pow(Math.abs(targetX-startX),2)+Math.pow(Math.abs(targetY-startY),2))/_speed;
		IntervalAction animAction = (IntervalAction)Animate.make(anim, true).autoRelease();
		IntervalAction moveAction = (IntervalAction)MoveBy.make(duration, targetX - startX, targetY - startY).autoRelease();
		sprite.runAction(moveAction);
		sprite.runAction((Action)RepeatForever.make(animAction).autoRelease());
		sprite.setFlipX(isFilpX);
	}
	public void SetRunAction(Sprite sprite, float startX, float startY, float targetX, float targetY, Callback cb)
	{
		int direction = GetDirectionByTan(targetX, targetY, startX, startY);
		boolean isFilpX=false;
		Animation anim = player_leftup_anim;
		if(direction==0)
			anim=player_up_anim;
		if(direction==1)
			anim=player_upright_anim;
		if(direction==2)
			anim=player_right_anim;
		if(direction==3)
			anim=player_rightdown_anim;
		if(direction==4)
			anim=player_down_anim;
		if(direction==5)
			{anim=player_downleft_anim;isFilpX=true;}
		if(direction==6)
			{anim=player_left_anim;isFilpX=true;}
		if(direction==7)
			{anim=player_leftup_anim;isFilpX=true;}
		float duration = (float) Math.sqrt(Math.pow(Math.abs(targetX-startX),2)+Math.pow(Math.abs(targetY-startY),2))/_speed;
		IntervalAction animAction = (IntervalAction)Animate.make(anim, true).autoRelease();
		IntervalAction moveAction = (IntervalAction)MoveBy.make(duration, targetX - startX, targetY - startY).autoRelease();
		moveAction.setCallback(cb);
		sprite.runAction(moveAction);
		sprite.runAction((Action)RepeatForever.make(animAction).autoRelease());
		sprite.setFlipX(isFilpX);
	}
	
	public void RunAnimation(Sprite sprite, float targetX, float targetY)
	{
		float startX = sprite.getPositionX();
		float startY = sprite.getPositionY();
		sprite.stopAllActions();
		SetRunAction(sprite, startX, startY, targetX, targetY);
	}
	public void RunAnimation(Sprite sprite, float targetX, float targetY, Callback cb)
	{
		float startX = sprite.getPositionX();
		float startY = sprite.getPositionY();
		sprite.stopAllActions();
		SetRunAction(sprite, startX, startY, targetX, targetY, cb);
	}
	
	public AnimationRole(String role, float durp, float speed, IAnimationCallback callback, AssetManager assetMgr) throws IOException
	{
		_role=role;
		_durp=durp;
		_callback=callback;
		_assetMgr = assetMgr;
		_speed=speed;
		InitAnimation();
	}
	
	public void InitAnimation() throws IOException
	{
		/*player_leftface_anim, player_rightface_anim, player_upface_anim, player_downface_anim, //face
		player_uprightface_anim, player_rightdownface_anim, player_leftupface_anim, player_downleftface_anim, 
		player_leftattack_anim, player_rightattack_anim, player_upattack_anim, player_downattack_anim, //attack
		player_uprightattack_anim, player_rightdownattack_anim, player_leftupattack_anim, player_downleftattack_anim
		*/
		player_down_anim = LoadAnimation(_role+File.separator+"run_down", 0, _durp, false);
		player_right_anim = LoadAnimation(_role+File.separator+"run_right", 0, _durp, false);
		player_rightdown_anim = LoadAnimation(_role+File.separator+"run_rightdown", 0, _durp, false);
		player_up_anim = LoadAnimation(_role+File.separator+"run_up", 0, _durp, false);
		player_upright_anim = LoadAnimation(_role+File.separator+"run_upright", 0, _durp, false);
		player_downleft_anim = LoadAnimation(_role+File.separator+"run_rightdown", 0, _durp, true);
		player_left_anim = LoadAnimation(_role+File.separator+"run_right", 0, _durp, true);
		player_leftup_anim = LoadAnimation(_role+File.separator+"run_upright", 0, _durp, true);
	}

	Animation CreateAnimationFromTexList(List<Texture2D> list, int id, float durp)
	{
		Animation anim;
		if(list.size()==2)
			anim = new Animation(id, durp, list.get(0), list.get(1));
		else if(list.size()==3)
			anim = new Animation(id, durp, list.get(0), list.get(1), list.get(2));
		else if(list.size()==4)
			anim = new Animation(id, durp, list.get(0), list.get(1), list.get(2), list.get(3));
		else if(list.size()==5)
			anim = new Animation(id, durp, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4));
		else if(list.size()==6)
			anim = new Animation(id, durp, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5));
		else if(list.size()==7)
			anim = new Animation(id, durp, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), list.get(6));
		else if(list.size()==8)
			anim = new Animation(id, durp, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), list.get(6), list.get(7));
		else if(list.size()==9)
			anim = new Animation(id, durp, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), list.get(6), list.get(7), list.get(8));
		else// if(list.size()==10)
			anim = new Animation(id, durp, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), list.get(6), list.get(7), list.get(8), list.get(9));

		anim.setCallback(_callback);
		return anim;
	}
	Animation LoadAnimation(String folderName,int id, float durp, boolean isFlipSide) throws IOException
	{
		String[] files = _assetMgr.list(folderName);
		List<Texture2D> texList = new ArrayList<Texture2D>();
		for(int i=0;i<files.length;i++)
		{
			Texture2D tex = Texture2D.makePNG(folderName + File.separator + files[i]);
			//if(isFlipSide)
			tex.setFlipX(isFlipSide);
			texList.add(tex);
		}
		return CreateAnimationFromTexList(texList, id, durp);
	}
	
	public void Dispose()
	{
		player_down_anim.autoRelease();
		player_right_anim.autoRelease();
		player_rightdown_anim.autoRelease();
		player_up_anim.autoRelease();
		player_upright_anim.autoRelease();
		player_downleft_anim.autoRelease();
		player_left_anim.autoRelease();
		player_leftup_anim.autoRelease();
	}
}
